﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using BUL;
using Public;

namespace Presentation
{
    public partial class frmManageBatch : Form
    {
        int userId = 2;
        int selectedBatch;
        int selectedProductId;
        int count = 1;
        bool selected = false;
        bool clear = true;
        string selectedProName;
        // if action = view => edit, add new product to existed batch
        // if action = create => edit, add new product to virtual table, and then can save, cancel to create a new batch or not
        string action = "view";
        BatchBUL batch = new BatchBUL();
        BatchDetails batchDetails = new BatchDetails(new Product(new ProductName(), new Brand(), new Unit()), new Batch());

        public frmManageBatch()
        {
            InitializeComponent();
        }

        private void frmManageBatch_Load(object sender, EventArgs e)
        {
            hideShowButton();
            // Load all kind of combobox
            this.LoadAllBatch();
            this.LoadAllProName();
            this.LoadAllUnit();
            this.LoadAllBrand();
            // change product name, product type change automatically at the same time
            this.txtProductType.ReadOnly = true;
            //
            this.selected = false;
            // select combobox and it do automatically event
            this.cbxBatch_SelectedIndexChanged(sender, e);
        }

        public int LoadAllBatch()
        {
            DataSet ds = this.batch.LoadAllBatch();
            cbxBatch.DataSource = ds.Tables[0];
            cbxBatch.DisplayMember = "batchId";
            cbxBatch.ValueMember = "batchId";
            if (action == "view")
            {
                return Convert.ToInt32(ds.Tables[0].Rows[0][0]);
            }
            else
            {
                return Convert.ToInt32(ds.Tables[0].Rows[ds.Tables[0].Rows.Count - 1][0]);
            }

        }

        public int LoadAllProName()
        {
            ProductNameBUL allProName = new ProductNameBUL();
            cbxProName.DataSource = allProName.GetAllProNameCBX().Tables[0];
            cbxProName.DisplayMember = "productName";
            cbxProName.ValueMember = "proNameId";
            return Convert.ToInt32(allProName.GetAllProNameCBX().Tables[0].Rows[0][0]);
        }

        public void LoadAllUnit()
        {
            UnitBUL allUnit = new UnitBUL();
            cbxUnit.DataSource = allUnit.GetAllUnitCBX().Tables[0];
            cbxUnit.DisplayMember = "unitName";
            cbxUnit.ValueMember = "unitId";
        }

        public void LoadAllBrand()
        {
            BrandBUL allBrand = new BrandBUL();
            cbxBrand.DataSource = allBrand.GetAllBrandCBX().Tables[0];
            cbxBrand.DisplayMember = "brandName";
            cbxBrand.ValueMember = "brandId";
        }

        private void btnCheck_Click(object sender, EventArgs e)
        {
            ProductBUL product = new ProductBUL();
            string barCode = txtBarCode.Text.Trim();
            if (barCode != "")
            {
                bool checkBarCode = product.checkBarCode(barCode);
                bool checkBcExistedInDgv = false;
                if (action == "create")
                {

                    int numOfRow = dgvProOfBat.Rows.Count;
                    for (int i = 0; i < numOfRow - 1; i++)
                    {
                        string bcInDgv = (string)dgvProOfBat[0, i].Value;
                        if (barCode == bcInDgv)
                        {
                            checkBcExistedInDgv = true;
                        }
                    }
                }
                if (checkBarCode || checkBcExistedInDgv)
                {
                    MessageBox.Show("This bar code is existed!");
                }
                else
                {
                    MessageBox.Show("This bar code can be used.", "Notice",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show("Please enter bar code!", "Notice",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnAddPN_Click(object sender, EventArgs e)
        {
            frmCreatePName frmProductName = new frmCreatePName();
            frmProductName.Show();
            this.Hide();
        }

        private void btnAddU_Click(object sender, EventArgs e)
        {
            frmCreatePUnit frmProductUnit = new frmCreatePUnit();
            frmProductUnit.Show();
            this.Hide();
        }

        private void btnAddBrand_Click(object sender, EventArgs e)
        {
            frmManageBrand frmBrandManagement = new frmManageBrand();
            frmBrandManagement.Show();
            this.Hide();
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            ProductBUL product = new ProductBUL();
            string barCode = txtBarCode.Text.Trim();
            if (barCode != "")
            {
                bool checkBarCode = product.checkBarCode(barCode);
                if (checkBarCode)
                {
                    MessageBox.Show("This bar code is existed!");
                }
                else
                {
                    // batch Id
                    batchDetails.Batch.BatchId = this.selectedBatch;
                    // barcode
                    batchDetails.Product.BarCode = this.txtBarCode.Text.Trim();
                    // producr name Id
                    string proNameS = cbxProName.SelectedValue.ToString();
                    batchDetails.Product.ProductName.PNameId = int.Parse(proNameS);
                    // unit Id
                    string proUnitS = cbxUnit.SelectedValue.ToString();
                    batchDetails.Product.Unit.UnitId = int.Parse(proUnitS);
                    // brand Id
                    string brandS = cbxBrand.SelectedValue.ToString();
                    batchDetails.Product.Brand.BrandId = int.Parse(brandS);
                    // unit price
                    float unitPrice = float.Parse(this.txtUnitPrice.Text);
                    batchDetails.Product.UnitPrice = unitPrice;
                    // quantity
                    int OQuantity = int.Parse(this.txtOQuantity.Text);
                    batchDetails.Product.Quantity = OQuantity;
                    batchDetails.Quantity = OQuantity;
                    // expired date
                    batchDetails.Product.ExpriredDate = dateTimepkED.Value.ToString("yyyy-MM-dd");
                    // total spending
                    batchDetails.Batch.TotalSpending = unitPrice * OQuantity;
                    batch.AddProductBatchDetails(batchDetails);
                    batchDetails.clearAll();
                    btnClear_Click(sender, e);
                    frmManageBatch_Load(sender, e);
                }
            }
            else
            {
                MessageBox.Show("Please enter bar code!", "Notice",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void selectedItem(object sender, DataGridViewCellEventArgs e)
        {
            this.selected = true;
            if (dgvProOfBat.Rows.Count > 1)
            {
                if (action == "view")
                {
                    int index = dgvProOfBat.CurrentRow.Index;
                    // barcode
                    this.txtBarCode.Text = dgvProOfBat.Rows[index].Cells[1].Value.ToString();
                    this.txtBarCode.ReadOnly = true;
                    // product name 
                    string proName = dgvProOfBat.Rows[index].Cells[2].Value.ToString();
                    cbxProName.SelectedIndex = cbxProName.FindStringExact(proName);
                    this.selectedProName = proName;
                    // product Type
                    this.txtProductType.Text = dgvProOfBat.Rows[index].Cells[3].Value.ToString();
                    // unit 
                    string proUnitS = dgvProOfBat.Rows[index].Cells[4].Value.ToString();
                    cbxUnit.SelectedIndex = cbxUnit.FindStringExact(proUnitS);
                    // brand 
                    string brandS = dgvProOfBat.Rows[index].Cells[5].Value.ToString();
                    cbxBrand.SelectedIndex = cbxBrand.FindStringExact(brandS);
                    // unit price
                    txtUnitPrice.Text = dgvProOfBat.Rows[index].Cells[9].Value.ToString();
                    // quantity
                    txtOQuantity.Text = dgvProOfBat.Rows[index].Cells[8].Value.ToString();
                    // expired date
                    dateTimepkED.Text = dgvProOfBat.Rows[index].Cells[6].Value.ToString();
                    // product Id
                    string productIdS = dgvProOfBat.Rows[index].Cells[0].Value.ToString();
                    this.selectedProductId = int.Parse(productIdS);
                }
                else
                {
                    int index = dgvProOfBat.CurrentRow.Index;
                    // barcode
                    this.txtBarCode.Text = dgvProOfBat.Rows[index].Cells[0].Value.ToString();
                    // product name 
                    string proName = dgvProOfBat.Rows[index].Cells[1].Value.ToString();
                    cbxProName.SelectedIndex = cbxProName.FindStringExact(proName);
                    this.selectedProName = proName;
                    // product Type
                    this.txtProductType.Text = dgvProOfBat.Rows[index].Cells[2].Value.ToString();
                    // unit 
                    string proUnitS = dgvProOfBat.Rows[index].Cells[3].Value.ToString();
                    cbxUnit.SelectedIndex = cbxUnit.FindStringExact(proUnitS);
                    // brand 
                    string brandS = dgvProOfBat.Rows[index].Cells[4].Value.ToString();
                    cbxBrand.SelectedIndex = cbxBrand.FindStringExact(brandS);
                    // expired date
                    dateTimepkED.Text = dgvProOfBat.Rows[index].Cells[5].Value.ToString();
                    // quantity
                    txtOQuantity.Text = dgvProOfBat.Rows[index].Cells[6].Value.ToString();
                    // unit price
                    txtUnitPrice.Text = dgvProOfBat.Rows[index].Cells[7].Value.ToString();
                }
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (this.selectedProductId != 0)
            {
                // quantity
                int OQuantity = int.Parse(this.txtOQuantity.Text);
                int CQuantity = Convert.ToInt32(this.batch.getCurrentQuantity(this.selectedProductId).Rows[0][0]);
                if (CQuantity <= OQuantity)
                {
                    // batch Id
                    batchDetails.Batch.BatchId = this.selectedBatch;
                    // product Id
                    batchDetails.Product.ProductId = this.selectedProductId;
                    // producr name Id
                    string proNameS = cbxProName.SelectedValue.ToString();
                    batchDetails.Product.ProductName.PNameId = int.Parse(proNameS);
                    // unit Id
                    string proUnitS = cbxUnit.SelectedValue.ToString();
                    batchDetails.Product.Unit.UnitId = int.Parse(proUnitS);
                    // brand Id
                    string brandS = cbxBrand.SelectedValue.ToString();
                    batchDetails.Product.Brand.BrandId = int.Parse(brandS);
                    // unit price
                    float unitPrice = float.Parse(this.txtUnitPrice.Text);
                    batchDetails.Product.UnitPrice = unitPrice;
                    // Original quantity
                    batchDetails.Product.Quantity = OQuantity;
                    batchDetails.Quantity = OQuantity;
                    // total spending
                    batchDetails.Batch.TotalSpending = unitPrice * OQuantity;
                    // expired date Convert.ToDateTime("2012-06-18 10:34:09")
                    batchDetails.Product.ExpriredDate = dateTimepkED.Value.ToString("yyyy-MM-dd");
                    //Update
                    batch.UpdateProductBatchDetails(batchDetails);
                    //batchDetails.clearAll();
                    btnClear_Click(sender, e);
                    getTotalSpending(this.batch);
                    frmManageBatch_Load(sender, e);
                }
                else
                {
                    MessageBox.Show("Original quantity is smaller than current quantity", "Notice",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show("You must click to any cell of the table", "Notice",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            if (clear)
            {
                this.LoadAllBatch();
            }
            this.LoadAllProName();
            this.LoadAllUnit();
            this.LoadAllBrand();
            this.txtBarCode.Text = "";
            this.txtOQuantity.Text = "";
            this.txtUnitPrice.Text = "";
            this.dateTimepkED.Text = DateTime.Now.ToString("yyyy-MM-dd");
            if (action == "view")
            {
                this.txtBarCode.ReadOnly = false;
            }
        }

        private void cbxBatch_SelectedIndexChanged(object sender, EventArgs e)
        {
            //this.selectedBatch = int.Parse(cbxBatch.SelectedValue.ToString());
            if (count == 1)
            {
                this.selectedBatch = LoadAllBatch();
                getTotalSpending(this.batch);
                dgvProOfBat.DataSource = this.batch.SelectProductOfBatch(selectedBatch);
                count++;
                this.lblImportedDate.Text = batch.getImportedDate(this.selectedBatch).Rows[0][0].ToString();
            }
            else
            {
                this.selectedBatch = int.Parse(cbxBatch.Text);
                DataTable dtDgv = this.batch.SelectProductOfBatch(selectedBatch);
                if (dtDgv.Rows.Count > 0)
                {
                    getTotalSpending(this.batch);
                    dgvProOfBat.DataSource = dtDgv;
                    dgvProOfBat.Columns[0].Visible = false;
                    dgvProOfBat.Columns[6].Visible = false;
                    this.lblImportedDate.Text = batch.getImportedDate(this.selectedBatch).Rows[0][0].ToString();
                }
                else
                {
                    this.lblTotalSpending.Text = "0";
                    dgvProOfBat.DataSource = null;
                    this.lblImportedDate.Text = "";

                }
                this.clear = false;
                btnClear_Click(sender, e);
            }
        }

        private void getTotalSpending(BatchBUL batch)
        {
            DataTable dt = batch.getTotalSpending(this.selectedBatch);
            double total = (double)dt.Rows[0][0];
            //string tail = " (x1000 VNĐ)";
            this.lblTotalSpending.Text = total.ToString();
        }

        private void hideShowButton()
        {
            if (action == "view")
            {
                // button for create batch
                this.btnAddVirtualProduct.Hide();
                this.btnSave.Hide();
                this.btnVirProUpdate.Hide();
                this.btnCancel.Hide();
                this.btnAdd.Show();
                this.btnUpdate.Show();
            }
            else
            {
                btnAdd.Hide();
                btnUpdate.Hide();
                btnAddVirtualProduct.Show();
                btnVirProUpdate.Show();
                btnSave.Show();
                btnCancel.Show();
            }
        }

        private void btnCreateBatch_Click(object sender, EventArgs e)
        {
            this.action = "create";
            hideShowButton();
            // clear datagrid view
            this.dgvProOfBat.DataSource = null;

            // Create new batch
            int batch = LoadAllBatch();
            this.selectedBatch = batch + 1;
            this.cbxBatch.Enabled = false;
            List<Batch> list = new List<Batch>();
            Batch newBatch = new Batch();
            newBatch.BatchId = this.selectedBatch;
            list.Add(newBatch);
            cbxBatch.DataSource = list;
            cbxBatch.DisplayMember = "batchId";
            cbxBatch.ValueMember = "batchId";
            // set imported date
            this.lblImportedDate.Text = DateTime.Now.ToString("yyyy-MM-dd");
            // set datagridview
            DataTable dt = new DataTable();
            dt.Columns.Add("Barcode");
            dt.Columns.Add("Product name");
            dt.Columns.Add("Product type");
            dt.Columns.Add("Unit");
            dt.Columns.Add("Brand");
            dt.Columns.Add("Expired date");
            dt.Columns.Add("Original quantity");
            dt.Columns.Add("Unit price");
            dgvProOfBat.DataSource = dt;
        }

        private void cbxProName_SelectedIndexChanged(object sender, EventArgs e)
        {
            ProductNameBUL proName = new ProductNameBUL();
            if (count == 2)
            {
                int proNameId = LoadAllProName();
                string typeName = Convert.ToString(proName.getTypeName(proNameId).Rows[0][0]);
                txtProductType.Text = typeName;
                count++;
            }
            else if (selected == true)
            {

            }
            else
            {
                string proNameS = cbxProName.SelectedValue.ToString();
                int proNameId = int.Parse(proNameS);
                string typeName = Convert.ToString(proName.getTypeName(proNameId).Rows[0][0]);
                txtProductType.Text = typeName;
            }

        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.action = "view";
            hideShowButton();
            frmManageBatch_Load(sender, e);
            this.cbxBatch.Enabled = true;
        }

        private void btnAddVirtualProduct_Click(object sender, EventArgs e)
        {
            ProductBUL product = new ProductBUL();
            string barCode = txtBarCode.Text.Trim();
            if (barCode != "")
            {
                bool checkBarCode = product.checkBarCode(barCode);
                if (checkBarCode)
                {
                    MessageBox.Show("This bar code is existed!");
                }
                else
                {
                    DataTable dt = new DataTable();
                    dt = (DataTable)dgvProOfBat.DataSource;
                    // 
                    DataRow workRow = dt.NewRow();
                    // bar code
                    workRow[0] = barCode;
                    // product name
                    workRow[1] = cbxProName.Text.Trim();
                    // product type
                    workRow[2] = txtProductType.Text.Trim();
                    // unit
                    workRow[3] = cbxUnit.Text.Trim();
                    // brand
                    workRow[4] = cbxBrand.Text.Trim();
                    // expired date ToString("yyyy-MM-dd") dateTimepkED.Value.ToString("yyyy-MM-dd")
                    workRow[5] = dateTimepkED.Value.ToString("yyyy-MM-dd");
                    // original quanity
                    workRow[6] = txtOQuantity.Text.Trim();
                    // unit price
                    workRow[7] = txtUnitPrice.Text.Trim();
                    dt.Rows.Add(workRow);
                    dgvProOfBat.DataSource = dt;
                    btnClear_Click(sender, e);
                    caculateTotalSpending();
                }
            }
            else
            {
                MessageBox.Show("Please enter bar code!", "Notice",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private float caculateTotalSpending()
        {
            int numOfRow = dgvProOfBat.Rows.Count;
            float totalSpendingCreate = 0;
            for (int i = 0; i < numOfRow - 1; i++)
            {
                string quantityS = (string)dgvProOfBat[6, i].Value;
                string unitPriceS = (string)dgvProOfBat[7, i].Value;
                int quantity = int.Parse(quantityS);
                float unitPrice = float.Parse(unitPriceS);
                totalSpendingCreate = totalSpendingCreate + (quantity * unitPrice);
                //string tail = " (x1000 VNĐ)";
                lblTotalSpending.Text = totalSpendingCreate.ToString();
            }
            return totalSpendingCreate;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            int numOfRow = dgvProOfBat.Rows.Count;
            if (numOfRow > 1)
            {
                batchDetails.clearAll();
                batchDetails = new BatchDetails(new Product(new ProductName(), new Brand(), new Unit()), new Batch());
                for (int i = 0; i < numOfRow - 1; i++)
                {
                    // bar code
                    batchDetails.Product.BarCode = (string)dgvProOfBat[0, i].Value;
                    // product name
                    batchDetails.Product.ProductName.PName = (string)dgvProOfBat[1, i].Value;
                    // unit
                    batchDetails.Product.Unit.UnitName = (string)dgvProOfBat[3, i].Value;
                    // brand
                    batchDetails.Product.Brand.BrandName = (string)dgvProOfBat[4, i].Value;
                    // expired date dateTimepkED.Value.ToString("yyyy-MM-dd");
                    batchDetails.Product.ExpriredDate = (string)dgvProOfBat[5, i].Value;
                    // original quanity
                    batchDetails.Quantity = int.Parse((string)dgvProOfBat[6, i].Value);
                    // current quantity
                    batchDetails.Product.Quantity = int.Parse((string)dgvProOfBat[6, i].Value);
                    // unit price
                    batchDetails.Product.UnitPrice = float.Parse((string)dgvProOfBat[7, i].Value);
                    // User Id - fix = 2
                    batchDetails.Batch.UserId = userId;
                    // importedDate yyyy-MM-dd HH:mm tt
                    batchDetails.Batch.ImportedDate = DateTime.Now.ToString("yyyy-MM-dd");
                    // totalSending
                    batchDetails.Batch.TotalSpending = float.Parse(this.lblTotalSpending.Text);
                    this.batch.AddBatchDetails(batchDetails);
                    //frmManageBatch_Load(sender, e);
                    //btnClear.PerformClick();
                    btnCancel.PerformClick();
                    btnCancel_Click(sender, e);
                    this.cbxBatch.Enabled = true;
                }
            }
            else
            {
                MessageBox.Show("Please input at least one product to save.", "Notice",
                       MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnVirProUpdate_Click(object sender, EventArgs e)
        {
            int selectedRow = 0;
            if (selectedRow > 0)
            {
                selectedRow = dgvProOfBat.SelectedCells[0].RowIndex;
                dgvProOfBat.Rows[selectedRow].SetValues(txtBarCode.Text, cbxProName.Text, txtProductType.Text,
                    cbxUnit.Text, cbxBrand.Text, dateTimepkED.Value.ToString("yyyy-MM-dd"), txtOQuantity.Text, txtUnitPrice.Text);
                btnClear_Click(sender, e);
                caculateTotalSpending();
            }
            else
            {
                MessageBox.Show("You must click to any cell of the table", "Notice",
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        private void ManageBatc_Closing(object sender, FormClosingEventArgs e)
        {
            DialogResult rs = MessageBox.Show("Are you really want to exist?", "Confirm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (rs == DialogResult.OK)
            {
                frmMain main = new frmMain();
                this.Hide();
                main.Show();
            }
            else
            {
                e.Cancel = true;
            }
        }
    }
}
